package com.ynr.invoice.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.ynr.common.utils.InvoiceHandler;
import com.ynr.common.utils.RedisTools;
import com.ynr.dao.ICompanyDao;
import com.ynr.dao.ICompanyInvoiceDao;
import com.ynr.dao.IInvoiceDao;
import com.ynr.invoice.service.IInvoiceService;
import com.ynr.voucher.model.InvoiceModel;
import com.ynr.voucher.service.IVoucherInvoiceService;
import com.ynr.voucher.service.IVoucherSalesService;

@Service("invoiceService")
public class InvoiceServiceImpl implements IInvoiceService {
	
	private static final Logger logger = LoggerFactory.getLogger(InvoiceServiceImpl.class);
	
	@Autowired
	private IInvoiceDao invoiceDao;
	
	@Autowired
	private ICompanyDao companyDao;
	
	@Autowired
	private ICompanyInvoiceDao companyInvoiceDao;
	
	@Autowired
	private IVoucherInvoiceService voucherInvoiceService;
	
	@Autowired
	private IVoucherSalesService voucherSalesService;
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Map<String, Object> uploadInvoice(String period, int companyId, String rootPath, MultipartFile multifile) {
		String filePath = rootPath + "/" + getGernarateFileName(multifile);
		try {
			FileUtils.copyInputStreamToFile(multifile.getInputStream(),
					new File(filePath));
		} catch (IOException e) {
			logger.error("InvoiceServiceImpl uploadInvoice method create file error : {}", e.toString());
		}
		Map<String, Object> invoiceBasicInfoMap = InvoiceHandler.recognize(filePath);
		if(invoiceBasicInfoMap.isEmpty()) {
			InvoiceModel invoice = new InvoiceModel();
			invoice.setFilePath(filePath);
			invoice.setRecStatus(2);
			invoice.setBillDate(period);
			invoiceDao.insertInvoiceEmpty(invoice);
			logger.debug("invoice id : {}", invoice.getId());
			companyInvoiceDao.insert(companyId, invoice.getId());
		} else {
			String invoiceDetailInfoJson = RedisTools.select(invoiceBasicInfoMap.get("fphm") + "&&&" + invoiceBasicInfoMap.get("fpdm"));
			if(invoiceDetailInfoJson == null || invoiceDetailInfoJson.isEmpty()) {
				Map<String, Object> invoiceDetailInfoMap = InvoiceHandler.query(invoiceBasicInfoMap);
				if(invoiceDetailInfoMap == null || invoiceDetailInfoMap.isEmpty()) {
					invoiceDao.insertInvoiceBasicInfo(invoiceBasicInfoMap, filePath, 2, period);
					long invoiceId = (long)invoiceBasicInfoMap.get("id");
					companyInvoiceDao.insert(companyId, invoiceId);
				} else {
					RedisTools.insert(invoiceDetailInfoMap.get("fphm") + "&&&" + invoiceDetailInfoMap.get("fpdm"), JSON.toJSONString(invoiceDetailInfoMap));
					InvoiceModel invoice = JSON.parseObject(JSON.toJSONString(invoiceDetailInfoMap), InvoiceModel.class);
					List<Map<String, Object>> goodsList = (List)invoiceDetailInfoMap.get("goodsData");
					invoiceDetailInfoMap.remove("goodsData");
					invoiceDao.insertInvoiceDetailInfo(invoiceDetailInfoMap, filePath, 1, 1, period);
					invoiceDao.insertInvoiceItem(goodsList, (long)invoiceDetailInfoMap.get("id"));
					companyInvoiceDao.insert(companyId, (long)invoiceDetailInfoMap.get("id"));
					
					//写凭证
					invoice.setBillDate(period);
					invoice.setId((long)invoiceDetailInfoMap.get("id"));
					Map<String, Object> companyMap = companyDao.getCompanyById(companyId);
					String companyName = (String)companyMap.get("name");
					if(companyName.equals(invoice.getGfMc())) {
						voucherInvoiceService.processInvoice(invoice, companyMap);
					} else if(companyName.equals(invoice.getXfMc())) {
						voucherSalesService.processSales(invoice, companyMap);
					}
				}
			} else {
				Map<String, Object> invoiceDetailInfoMap = (Map)JSON.parse(invoiceDetailInfoJson);
				InvoiceModel invoice = JSON.parseObject(JSON.toJSONString(invoiceDetailInfoMap), InvoiceModel.class);
				List<Map<String, Object>> goodsList = (List)invoiceDetailInfoMap.get("goodsData");
				invoiceDetailInfoMap.remove("goodsData");
				invoiceDao.insertInvoiceDetailInfo(invoiceDetailInfoMap, filePath, 1, 1, period);
				invoiceDao.insertInvoiceItem(goodsList, (long)invoiceDetailInfoMap.get("id"));
				companyInvoiceDao.insert(companyId, (long)invoiceDetailInfoMap.get("id"));
				
				//写凭证
				invoice.setBillDate(period);
				invoice.setId((long)invoiceDetailInfoMap.get("id"));
				Map<String, Object> companyMap = companyDao.getCompanyById(companyId);
				String companyName = (String)companyMap.get("name");
				if(companyName.equals(invoice.getGfMc())) {
					voucherInvoiceService.processInvoice(invoice, companyMap);
				} else if(companyName.equals(invoice.getXfMc())) {
					voucherSalesService.processSales(invoice, companyMap);
				}
			}
		}
		return new HashMap<>();
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Map<String, Object> updateInvoiceBasicInfo(Map<String, String[]> dataMap) {
		Map<String, Object> retMap = new HashMap<>();
		try {
			long invoiceId = Long.valueOf(dataMap.get("invoice_id")[0]);
			Map<String, Object> invoiceBasicInfoMap = new HashMap<>();
			for(Entry<String, String[]> entry : dataMap.entrySet()) {
				invoiceBasicInfoMap.put(entry.getKey(), entry.getValue()[0]);
			}
			invoiceBasicInfoMap.remove("invoice_id");
			String invoiceDetailInfoJson = RedisTools.select(invoiceBasicInfoMap.get("fphm") + "&&&" + invoiceBasicInfoMap.get("fpdm"));
			if(invoiceDetailInfoJson == null || invoiceDetailInfoJson.isEmpty()) {
				Map<String, Object> invoiceDetailInfoMap = InvoiceHandler.query(invoiceBasicInfoMap);
				if(invoiceDetailInfoMap.isEmpty()) {
					//查无此票
					return new HashMap<String, Object>();
				} else {
					RedisTools.insert(invoiceDetailInfoMap.get("fphm") + "&&&" + invoiceDetailInfoMap.get("fpdm"), JSON.toJSONString(invoiceDetailInfoMap));
					InvoiceModel invoice = JSON.parseObject(JSON.toJSONString(invoiceDetailInfoMap), InvoiceModel.class);
					List<Map<String, Object>> goodsList = (List)invoiceDetailInfoMap.get("goodsData");
					invoiceDetailInfoMap.remove("goodsData");
					invoiceDao.updateInvoiceDetailInfo(invoiceDetailInfoMap, 1, 1, invoiceId);
					invoiceDao.insertInvoiceItem(goodsList, invoiceId);
					
					//写凭证
					invoice.setBillDate(""+invoiceDetailInfoMap.get("bill_date"));
					Map<String, Object> companyMap = companyDao.getCompanyByInvoiceId(invoiceId);
					String companyName = (String)companyMap.get("name");
					if(companyName.equals(invoice.getGfMc())) {
						voucherInvoiceService.processInvoice(invoice, companyMap);
					} else if(companyName.equals(invoice.getXfMc())) {
						voucherSalesService.processSales(invoice, companyMap);
					}
				}
			} else {
				Map<String, Object> invoiceDetailInfoMap = (Map)JSON.parse(invoiceDetailInfoJson);
				InvoiceModel invoice = JSON.parseObject(JSON.toJSONString(invoiceDetailInfoMap), InvoiceModel.class);
				List<Map<String, Object>> goodsList = (List)invoiceDetailInfoMap.get("goodsData");
				invoiceDetailInfoMap.remove("goodsData");
				invoiceDao.updateInvoiceDetailInfo(invoiceDetailInfoMap, 1, 1, invoiceId);
				invoiceDao.insertInvoiceItem(goodsList, invoiceId);
				
				//写凭证
				invoice.setBillDate(""+invoiceDetailInfoMap.get("bill_date"));
				Map<String, Object> companyMap = companyDao.getCompanyByInvoiceId(invoiceId);
				String companyName = (String)companyMap.get("name");
				if(companyName.equals(invoice.getGfMc())) {
					voucherInvoiceService.processInvoice(invoice, companyMap);
				} else if(companyName.equals(invoice.getXfMc())) {
					voucherSalesService.processSales(invoice, companyMap);
				}
			}
			retMap.put("errorCode", "0000");
		} catch (Exception e) {
			logger.error("updateInvoiceBasicInfo error : {}", e.toString());
			retMap.put("errorCode", "0001");
		}
		return retMap;
	}

	@Override
	public Map<String, Object> getUnrecognizedInvoices() {
		Map<String, Object> retMap = new HashMap<>();
		List<Map<String, Object>> unrecognizedInvoicesBasicInfoList = invoiceDao.getUnrecognizedInvoices();
		retMap.put("data", unrecognizedInvoicesBasicInfoList);
		return retMap;
	}

	@Override
	public Map<String, Object> deleteInvoice(List<String> idList) {
		Map<String, Object> retMap = new HashMap<>();
		try {
			for(String invoiceId : idList) {
				invoiceDao.deleteInvoice(Long.valueOf(invoiceId));
			}
			retMap.put("errorCode", "0000");
		} catch(Exception e) {
			logger.error("deleteInvoice error : {}", e.toString());
			retMap.put("errorCode", "0001");
		}
		return retMap;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Map<String, Object> manualInput(String fphm, String fpdm, String kprq, String checkCode, String noTaxAmount,
			String billDate, String companyId) {
		Map<String, Object> invoiceBasicInfoMap = new HashMap<>();
		invoiceBasicInfoMap.put("fphm", fphm);
		invoiceBasicInfoMap.put("fpdm", fpdm);
		invoiceBasicInfoMap.put("kprq", kprq);
		invoiceBasicInfoMap.put("checkCode", checkCode);
		invoiceBasicInfoMap.put("noTaxAmount", noTaxAmount);
		String invoiceDetailInfoJson = RedisTools.select(fphm + "&&&" + fpdm);
		if(invoiceDetailInfoJson == null || invoiceDetailInfoJson.isEmpty()) {
			Map<String, Object> invoiceDetailInfoMap = InvoiceHandler.query(invoiceBasicInfoMap);
			if(invoiceDetailInfoMap == null || invoiceDetailInfoMap.isEmpty()) {
				invoiceDao.insertInvoiceBasicInfo(invoiceBasicInfoMap, "", 2, billDate);
				long invoiceId = (long)invoiceBasicInfoMap.get("id");
				companyInvoiceDao.insert(Long.valueOf(companyId), invoiceId);
			} else {
				RedisTools.insert(invoiceDetailInfoMap.get("fphm") + "&&&" + invoiceDetailInfoMap.get("fpdm"), JSON.toJSONString(invoiceDetailInfoMap));
				List<Map<String, Object>> goodsList = (List)invoiceDetailInfoMap.get("goodsData");
				invoiceDetailInfoMap.remove("goodsData");
				invoiceDao.insertInvoiceDetailInfo(invoiceDetailInfoMap, "", 1, 1, billDate);
				invoiceDao.insertInvoiceItem(goodsList, (long)invoiceDetailInfoMap.get("id"));
				companyInvoiceDao.insert(Long.valueOf(companyId), (long)invoiceDetailInfoMap.get("id"));
			}
		} else {
			Map<String, Object> invoiceDetailInfoMap = (Map)JSON.parse(invoiceDetailInfoJson);
			List<Map<String, Object>> goodsList = (List)invoiceDetailInfoMap.get("goodsData");
			invoiceDetailInfoMap.remove("goodsData");
			invoiceDao.insertInvoiceDetailInfo(invoiceDetailInfoMap, "", 1, 1, billDate);
			invoiceDao.insertInvoiceItem(goodsList, (long)invoiceDetailInfoMap.get("id"));
			companyInvoiceDao.insert(Long.valueOf(companyId), (long)invoiceDetailInfoMap.get("id"));
		}
		return new HashMap<>();
	}

	private String getGernarateFileName(MultipartFile file) {
		Random rdm = new Random(System.currentTimeMillis());
		String extendName = file.getOriginalFilename().substring(
				file.getOriginalFilename().lastIndexOf(".") + 1);
		return System.currentTimeMillis() + Math.abs(rdm.nextInt())
				% 1000 + (extendName == null ? ".unknown" : "." + extendName);
	}

	
}
